// FIFO16_REP.v
// This just instantiates a few fifos side-by-side to widen the data stream. They're 4k deep.
// Copyright 2006, Pico Computing, Inc.

module FIFO16_REP #(
   parameter REPS = 8,
   parameter ALMOST_FULL_OFFSET = 12'h010,
   parameter ALMOST_EMPTY_OFFSET = 12'h100,
   parameter DATA_WIDTH = 36,
   parameter FIRST_WORD_FALL_THROUGH = "TRUE"
) (
   output ALMOSTEMPTY,
   output ALMOSTFULL,
   output [31:0] DO,
   output EMPTY,
   output FULL,
   output [11:0] RDCOUNT,
   output RDERR,
   output [11:0] WRCOUNT,
   output WRERR,
   input  [31:0] DI,
   input  RDCLK,
   input  RDEN,
   input  RST,
   input  WRCLK,
   input  WREN
);

// the first fifo will drive all the control outputs, and we'll ignore the other fifos
genvar i;
generate for (i=0; i < REPS; i=i+1) begin:fifos

if (i==0) begin:fifos

// if there's only one fifo in all, then make it the full 32(36) bits wide.
if (REPS==1) begin: singlefifo

FIFO16 #(
   .ALMOST_FULL_OFFSET(ALMOST_FULL_OFFSET), // Sets almost full threshold
   .ALMOST_EMPTY_OFFSET(ALMOST_EMPTY_OFFSET), // Sets the almost empty threshold
   .DATA_WIDTH(36), // Sets data width to 4, 9, 18, or 36
   .FIRST_WORD_FALL_THROUGH(FIRST_WORD_FALL_THROUGH) // Sets the FIFO FWFT to "TRUE" or "FALSE"
) F16O (
   .DO(DO[31:0]), // 32-bit data output
   .DOP(), // 4-bit parity data output
   
   .ALMOSTEMPTY(ALMOSTEMPTY), // 1-bit almost empty output flag
   .ALMOSTFULL(ALMOSTFULL), // 1-bit almost full output flag
   .EMPTY(EMPTY), // 1-bit empty output flag
   .FULL(FULL), // 1-bit full output flag
   .RDCOUNT(RDCOUNT), // 12-bit read count output
   .RDERR(RDERR), // 1-bit read error output
   .WRCOUNT(WRCOUNT), // 12-bit write count output
   .WRERR(WRERR), // 1-bit write error
   
   .DI(DI[31:0]), // 32-bit data input
   .DIP(4'h0), // 4-bit partity input
   .RDCLK(RDCLK), // 1-bit read clock input
   .RDEN(RDEN), // 1-bit read enable input
   .RST(RST), // 1-bit reset input
   .WRCLK(WRCLK), // 1-bit write clock input
   .WREN(WREN) // 1-bit write enable input
);

end else begin: multififo

FIFO16 #(
   .ALMOST_FULL_OFFSET(ALMOST_FULL_OFFSET), // Sets almost full threshold
   .ALMOST_EMPTY_OFFSET(ALMOST_EMPTY_OFFSET), // Sets the almost empty threshold
   .DATA_WIDTH(4), // Sets data width to 4, 9, 18, or 36
   .FIRST_WORD_FALL_THROUGH(FIRST_WORD_FALL_THROUGH) // Sets the FIFO FWFT to "TRUE" or "FALSE"
) F16O (
   .DO(DO[i*4+3:i*4]), // 32-bit data output
   .DOP(), // 4-bit parity data output
   
   .ALMOSTEMPTY(ALMOSTEMPTY), // 1-bit almost empty output flag
   .ALMOSTFULL(ALMOSTFULL), // 1-bit almost full output flag
   .EMPTY(EMPTY), // 1-bit empty output flag
   .FULL(FULL), // 1-bit full output flag
   .RDCOUNT(RDCOUNT), // 12-bit read count output
   .RDERR(RDERR), // 1-bit read error output
   .WRCOUNT(WRCOUNT), // 12-bit write count output
   .WRERR(WRERR), // 1-bit write error
   
   .DI(DI[i*4+3:i*4]), // 32-bit data input
   .DIP(4'h0), // 4-bit partity input
   .RDCLK(RDCLK), // 1-bit read clock input
   .RDEN(RDEN), // 1-bit read enable input
   .RST(RST), // 1-bit reset input
   .WRCLK(WRCLK), // 1-bit write clock input
   .WREN(WREN) // 1-bit write enable input
);
end // REPS==1
end else begin:more_fifos

FIFO16 #(
   .ALMOST_FULL_OFFSET(ALMOST_FULL_OFFSET), // Sets almost full threshold
   .ALMOST_EMPTY_OFFSET(ALMOST_EMPTY_OFFSET), // Sets the almost empty threshold
   .DATA_WIDTH(4), // Sets data width to 4, 9, 18, or 36
   .FIRST_WORD_FALL_THROUGH(FIRST_WORD_FALL_THROUGH) // Sets the FIFO FWFT to "TRUE" or "FALSE"
) F16O (
   .DO(DO[i*4+3:i*4]), // 32-bit data output
   .DOP(), // 4-bit parity data output
   
   .DI(DI[i*4+3:i*4]), // 32-bit data input
   .DIP(4'h0), // 4-bit partity input
   .RDCLK(RDCLK), // 1-bit read clock input
   .RDEN(RDEN), // 1-bit read enable input
   .RST(RST), // 1-bit reset input
   .WRCLK(WRCLK), // 1-bit write clock input
   .WREN(WREN) // 1-bit write enable input
);

end

end endgenerate

endmodule
